using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Timers;

namespace Shrapnel
{
	/// <summary>
	/// A class capable of performing automatic panning on a view
	/// </summary>
	internal class AutomaticPanner
	{
		public delegate void UpdatePanningHandler();

		/// <summary>
		/// The viewstate to pan
		/// </summary>
		private ViewState viewState;

		/// <summary>
		/// The direction to pan to
		/// </summary>
		private PointF direction;

		/// <summary>
		/// Are we currently active?
		/// </summary>
		private bool isActive;

		/// <summary>
		/// Update interval in milliseconds for the automatic panner
		/// </summary>
		private float updateInterval;

		/// <summary>
		/// Update event fired each "panning" tick
		/// </summary>
		public event UpdatePanningHandler OnUpdate;


		private Timer updateTimer;
		

		/// <summary>
		/// The direction to pan to
		/// </summary>
		public PointF Direction
		{
			get { return direction; }
			set { direction = value; }
		}

		/// <summary>
		/// Create a new instance
		/// </summary>
		/// <param name="viewState"></param>
		/// <param name="updateInterval">Update interval in milliseconds</param>
		public AutomaticPanner(ViewState viewState, int updateInterval)
		{
			this.isActive = false;
			this.viewState = viewState;
			this.updateInterval = updateInterval;

			updateTimer = new Timer(updateInterval);
			updateTimer.AutoReset = true;
			updateTimer.Elapsed += HandleTimerElapsed;
		}


		/// <summary>
		/// Start panning, if we're not already doing so, and set the direction
		/// </summary>
		/// <param name="direction"></param>
		public void Start(PointF direction)
		{
			this.direction = direction;

			if (!isActive)
			{
				updateTimer.Start();
				isActive = true;
			}
		}

		/// <summary>
		/// Stop panning if we're currently doing so
		/// </summary>
		public void Stop()
		{
			if (isActive)
			{
				updateTimer.Stop();
				isActive = false;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void HandleTimerElapsed(object sender, ElapsedEventArgs e)
		{
			if (isActive && OnUpdate != null)
			{
				viewState.Offset += new SizeF(direction);
				OnUpdate();			
			}
		}
	}
}
